const Koa = require("koa");
const Router = require("koa-router");
const log4js = require("./utils/log4js");
const { BLACK_IP_LIST, FORBIDDEN_CODE } = require("./config");
const MyError = require("./exception");
const bodyParser = require("koa-bodyparser");
const jwt = require("koa-jwt");
const loggerMiddleware = require("./middlewares/logger");
const corsMiddleware = require("./middlewares/cors");

// 请求大小限制
const requestLimit = "5120kb";

// 临时 IP 黑名单
const tempBlackIpList = [];

class Server {
  constructor() {
    this.server = new Koa();
    this.router = new Router(); // 实例化 Router
    this.server.use(bodyParser({ jsonLimit: requestLimit }));
    this.server.keys = ["hashan"];

    // 日志配置
    this.server.use(loggerMiddleware);

    //请求头处理
    this.server.use(corsMiddleware);

    // JWT 中间件
    this.server.use(
      jwt({ secret: "hashan" }).unless({
        path: ["/api/login", "/api/test"],
      })
    );

    // 使用 router 中间件
    this.server.use(this.router.routes());
    this.server.use(this.router.allowedMethods());
  }

  // 路由处理
  setRoute(path, handlerFunction) {
    const handler = async (ctx) => {
      const requestClientIp = getClientIp(ctx);
      if (
        !requestClientIp ||
        BLACK_IP_LIST.includes(requestClientIp) ||
        tempBlackIpList.includes(requestClientIp)
      ) {
        console.error(`ip ${requestClientIp} is in blackList, banned!`);
        ctx.status = 403;
        ctx.body = FORBIDDEN_CODE;
        return;
      }

      const event = ctx.request.body;
      if (event?.pageSize === 100) {
        tempBlackIpList.push(requestClientIp);
        console.log("tempBlackIpList = " + JSON.stringify(tempBlackIpList));
      }
      let result;
      try {
        let params;
        if (event.file) {
          let eventCopy = { ...event };
          eventCopy.file = undefined;
          params = JSON.stringify(eventCopy);
        } else {
          params = JSON.stringify(event);
        }
        result = await handlerFunction(event, ctx);
      } catch (e) {
        if (e instanceof MyError) {
          result = {
            code: e.code,
            message: e.message,
            data: null,
          };
        } else {
          result = {
            code: 500,
            data: null,
            message: "server error",
          };
        }
        log4js.error(
          `IP:${ctx.request.ip}-请求地址:${ctx.request.url}-报错信息:${e.message}`
        );
      }
      ctx.body = result;
    };
    const contextPath = "/api";
    this.router.post(contextPath + path, handler); // 使用 router 实例
  }
  // 启动监听服务
  listen(port, ...args) {
    this.server.listen(port, ...args);
    console.log(`server start at ${port}`);
  }
}

/**
 * 获取真实客户端 ip
 * @param ctx
 * @returns {*|string}
 */
function getClientIp(ctx) {
  if (!ctx) {
    return "";
  }
  return ctx.headers["x-forwarded-for"] || ctx.request.ip;
}

module.exports = Server;
